package com.platform.server.util;

import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;

public class RSAUtil {
	public static final String CHARSET = "UTF-8";
	public static final String privateKey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANT+Fu/TgR+PmUN3"+
		"pxMkUu5odZezPLySac7SyQA95ankKqCc13OBSMP2xzoEtRbJv41YvE7nn3PZuGFv"+
		"atYsNn0xYx1ffbDcUaIbf/YUBi5s0GU0u/2lc+W6PpA6P1Nha0x5v9G0JsPI1cXH"+
		"TN5JXe8/JneQfuUkQiARG+J7xsxbAgMBAAECgYEAzS38sImiQOIXdbvlMfZzAYGV"+
		"jk62+r1cukWqJdZ60J+hRNnyXy2zCDxJjaWNQWeWZLaPqL9Ohs685PftBmbPESal"+
		"WdIjADijM0HKDFS6GKEYd3CcyJPRT1joRDMnyr7GhxpngcvKTglkc0P+eC0uzQRy"+
		"a4mu9464TDhrNG7MfGECQQD2NXnzkUs5PXG2fqWm/dg2eJH2NFmrtEPno9Ah1aOh"+
		"lGIBrKFmin3nnPyA5ZW8slyGlIEJYWjgMAWeKdsjZmUxAkEA3XZ0dqdLpG+AojJm"+
		"DDcc7nkbGv3UL7AOdBLM3NVxU1D3PQEZTF+PJkmZb+s+Cl+Iw96Wz4rVcoEbeNTa"+
		"o7vXSwJAWEbwRN6RhCJ9xRs/tdJKVa2BWC+I/0GRH1ri417AXszfHw6QiD2byxHE"+
		"j0rCF3g0KKTSZ1Sfz9IoEX+cbOLn4QJAVJP5tJr9y4X+BXPj/0RJG1ZLIMrR74h4"+
		"bKIFdU1a42vnkHfL9pwEKqYvIEwiPInxzIRE6mxmSj2+hS4ddiy18wJAVKs0dDQO"+
		"3ceckoHcsxwqZdlBCjjrOe+zL9yMl3mXSKytMHEliLoTnM6F1t2WOuPk+qcc8LCV"+
		"B1LV/vhVPg98tg==";
	public static final String RSA_ALGORITHM = "RSA";
	
	public static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDU/hbv04Efj5lDd6cTJFLuaHWXszy8kmnO0skAPeWp5CqgnNdzgUjD9sc6BLUWyb+NWLxO559z2bhhb2rWLDZ9MWMdX32w3FGiG3/2FAYubNBlNLv9pXPluj6QOj9TYWtMeb/RtCbDyNXFx0zeSV3vPyZ3kH7lJEIgERvie8bMWwIDAQAB";
	
	
	/**
	 * 私钥解密
	 * 
	 * @param data
	 * @param privateKey
	 * @return
	 */
	public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
		try {
			Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data),
					privateKey.getModulus().bitLength()), CHARSET);
		} catch (Exception e) {
			throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
		}
	}

	/**
	 * 得到私钥
	 * 
	 * @param privateKey
	 *            密钥字符串（经过base64编码）
	 * @throws Exception
	 */
	public static RSAPrivateKey getPrivateKey(String privateKey)
			throws NoSuchAlgorithmException, InvalidKeySpecException {
		// 通过PKCS#8编码的Key指令获得私钥对象
		KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
		RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
		return key;
	}

	private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
		int maxBlock = 0;
		if (opmode == Cipher.DECRYPT_MODE) {
			maxBlock = keySize / 8;
		} else {
			maxBlock = keySize / 8 - 11;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] buff;
		int i = 0;
		try {
			while (datas.length > offSet) {
				if (datas.length - offSet > maxBlock) {
					buff = cipher.doFinal(datas, offSet, maxBlock);
				} else {
					buff = cipher.doFinal(datas, offSet, datas.length - offSet);
				}
				out.write(buff, 0, buff.length);
				i++;
				offSet = i * maxBlock;
			}
		} catch (Exception e) {
			throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
		}
		byte[] resultDatas = out.toByteArray();
		IOUtils.closeQuietly(out);
		return resultDatas;
	}
	
	public static String encryptString(PublicKey publicKey, String plaintext) {  
        if (publicKey == null || plaintext == null) {  
            return null;  
        }  
        byte[] data = plaintext.getBytes();  
        try {  
            byte[] en_data = encrypt(publicKey, data);  
            return new String(Hex.encodeHex(en_data));  
        } catch (Exception ex) {  
        }  
        return null;  
    } 
	
	public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {  
        Cipher ci = Cipher.getInstance(RSA_ALGORITHM);  
        ci.init(Cipher.ENCRYPT_MODE, publicKey);  
        return ci.doFinal(data);  
    }  
	
	//测试
		public static void main1(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
			System.out.println(privateDecrypt(
					"06cBVO9zY2bsuug3Q8TjdYTiCurhmAOaz0lGo5Sh+XwKTcoOO/7AtHw7HRvq4l8iA1QccD21luMnqGq4UwdnCXlkta4vp7jIo8gg6FzYSQ96G8/zRnjVrdYdgVr55VRDYNVL4nViUqck8daF9vlNOJcheDvRwpRZVXDFrG2UD8g=",
					getPrivateKey(privateKey)));
			System.out.println(privateDecrypt(
					"L+QNFAkHUeuQuamqjyBeEHoX/n3HZRpth1NFg7jeDGImuntjX18v0F8mtxELvsdd5aWKSjWQDozlSvOCGc9WWFlZxFKMTo34sfxE4enKGxkeXqkHs674ALQnThx8xCR8ZhDUTpV06rxERj6jCOUPdvYrDBEIe8TataWhoWix4v4=",
					getPrivateKey(privateKey)));
		}
}
